package com.mldong.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mldong.base.CommonPage;
import com.mldong.dict.CustomDictService;
import com.mldong.dict.DictScanner;
import com.mldong.dict.model.DictModel;
import com.mldong.modules.sys.dto.DictPageParam;
import com.mldong.modules.sys.dto.DictParam;
import com.mldong.modules.sys.entity.DictItem;
import com.mldong.modules.sys.enums.DictDataTypeEnum;
import com.mldong.modules.sys.service.DictItemService;
import com.mldong.modules.sys.vo.DictVO;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mldong.modules.sys.entity.Dict;
import com.mldong.modules.sys.mapper.DictMapper;
import com.mldong.modules.sys.service.DictService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 字典 服务实现类
 * </p>
 *
 * @author mldong
 * @since 2022-10-23
 */
@Service
@RequiredArgsConstructor
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {
    private final DictItemService dictItemService;
    private final DictScanner dictScanner;
    private final List<CustomDictService> customDictServices;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(DictParam param) {
        param.setId(null);
        Dict Dict = new Dict();
        BeanUtil.copyProperties(param, Dict);
        return super.save(Dict);
    }

    @Override
    public boolean update(DictParam param) {
        Dict Dict = new Dict();
        BeanUtil.copyProperties(param, Dict);
        return super.updateById(Dict);
    }

    @Override
    public CommonPage<DictVO> page(DictPageParam param) {
        IPage<DictVO> page = param.buildMpPage();

        QueryWrapper queryWrapper = param.buildQueryWrapper();
        queryWrapper.eq("t.is_deleted",0);
        if(StrUtil.isBlank(param.getOrderBy())){
            queryWrapper.orderByAsc("t.sort");
        }
        List<DictVO> list = baseMapper.selectCustom(page, queryWrapper);
        page.setRecords(list);
        return CommonPage.toPage(page);
    }
    @Override
    public DictVO findById(Long id) {
        return baseMapper.findById(id);
    }

    @Override
    public List<cn.hutool.core.lang.Dict> getByDictType(String dictType) {
        // 优先级顺序：自定义字典服务->db->枚举类
        for (int i = 0,len=customDictServices.size(); i < len; i++) {
            // 自定义字典的优先级最高
            CustomDictService customDictService = customDictServices.get(i);
            Map<String,Object> map = new HashMap<>();
            map.put("dictType", dictType);
            DictModel dictModel = customDictService.getByDictKey(map);
            if(dictModel!=null){
                return dictModel.toDictList();
            }
        }
        List<cn.hutool.core.lang.Dict> dictList = new ArrayList<>();
        Dict dict = selectOneByDictType(dictType);
        if(dict == null){
            // 不存在，则从枚举中获取
            DictModel dictModel = dictScanner.getDictMap().get(dictType);
            if(dictModel!=null){
                return dictModel.toDictList();
            }
            return dictList;
        }
        List<DictItem> dictItemList =dictItemService.findByDictId(dict.getId());
        dictItemList.forEach(item->{
            if(ObjectUtil.equals(dict.getDataType(), DictDataTypeEnum.INTEGER.getCode())){
                // 整型
                dictList.add(cn.hutool.core.lang.Dict.create().set("label",item.getName()).set("value", Convert.toInt(item.getCode())));
            } else {
                dictList.add(cn.hutool.core.lang.Dict.create().set("label",item.getName()).set("value",item.getCode()));
            }
        });
        return dictList;
    }

    @Override
    public Dict selectOneByDictType(String dictType) {
        List<Dict> list = baseMapper.selectList(Wrappers.lambdaQuery(Dict.class)
                .eq(Dict::getEnabled,1)
                .eq(Dict::getCode,dictType));
        if(!list.isEmpty()){
            return list.get(0);
        }
        return null;
    }
}
